/*
 * This file is part of SND.
 *
 * Sensor Network Deployer
 * Copyright (C)  Michael Morckos 2008 <mikey.morckos@gmail.com>
 * 
 * SND is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * SND is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with SND.  If not, see <http://www.gnu.org/licenses/>.
 */

import javax.swing.*;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.*;
import java.awt.*;
import java.util.LinkedList;

public class Graph_Panel extends JPanel {
	
	private static final long serialVersionUID = 1L;
	
	private final int IDLE = 0;
	private final int DRAW_NODES = 1;
	private final int DRAW_EDGES = 2;
	private final int DRAW_AREA = 3;

	private Graphics2D g2d;
	private Rectangle2D.Double r2dNodes [];
	
	private int width, height;
	private int [] render_buffer;
	
	private LinkedList nodes;
	private LinkedList edges;
	
	private boolean busy;
	
	private int x [], y [];

	public Graph_Panel() {
		
		super(null);
		render_buffer = new int [3];
		setBackground(Color.WHITE);
		
		busy = false;
	}
	
	public void reset() {
		
		repaint();
		removeAll();
		
		render_buffer[0] = IDLE;
		render_buffer[1] = IDLE;
		render_buffer[2] = IDLE;
		
		nodes = null;
		edges = null;
		
		busy = false;
		repaint();
	}
	
	/* DRAWING SENSOR NODES */
	public void drawNodes(LinkedList nodes) {
		
        this.nodes = nodes;
        
        busy = true;
		render_buffer[0] = DRAW_NODES;
		repaint();
	}
	
	/* DRAWING EDGES */
    public void drawEdges(LinkedList edges) {
		
    	this.edges = edges;
    	
    	render_buffer[1] = DRAW_EDGES;
    	repaint();
	}
    
    /* DRAWING AREA */
    public void drawArea(int width, int height) {
		
    	this.width = width;
    	this.height = height;
    	
    	render_buffer[2] = DRAW_AREA;
    	repaint();
	}
    
    public void paint(Graphics g) {
    
    	g2d = (Graphics2D) g;
    	
    	for(int i = 0; i < 3; i++) {
    		switch(render_buffer[i]) {
    	        case DRAW_AREA : drawAreaHelper(g2d);
    	        case IDLE: break;
    	    }		
    	}
    	
    	drawNodesHelper(g2d);
    	drawEdgesHelper(g2d);
    	drawCoordinateSystem(760, 610, g2d);
    }
    
    /* DRAWING SENSOR NODES */
    public void drawNodesHelper(Graphics2D g2d) {
    	
    	if(render_buffer[0] == DRAW_NODES && nodes != null) {
    		g2d.setPaint(Color.BLACK);
        	
        	for(int i = 0; i < nodes.size(); i++) {
        		if(!((Node)nodes.get(i)).getSTATUS())
        			g2d.setPaint(Color.red);
        		else
        			g2d.setPaint(Color.BLACK);
        		
        		g2d.fillRect(((Node)nodes.get(i)).getX(), ((Node)nodes.get(i)).getY(), 5, 5);
        		g2d.drawString(String.valueOf(i), ((Node)nodes.get(i)).getX(), ((Node)nodes.get(i)).getY());
        	}	
        	
        	repaint();
    	}
    }
    
    /* DRAWING EDGES */
    public void drawEdgesHelper(Graphics2D g2d) {
        
    	if(render_buffer[1] == DRAW_EDGES && edges != null) {
    		g2d.setPaint(Color.black);
    		
    		for(int i = 0; i < edges.size(); i++)
    		    g2d.drawLine(((Edge)edges.get(i)).getX_S(), ((Edge)edges.get(i)).getY_S(), 
    		    		((Edge)edges.get(i)).getX_D(), ((Edge)edges.get(i)).getY_D());
    	}
    }
    
    /* DRAWING AREA */
    public void drawAreaHelper(Graphics2D g2d) {
    	
    	Rectangle2D.Double r2d = new Rectangle2D.Double(50, 50, width, height);
	    g2d.draw(r2d);
    }
    
    /* DRAWING COORDINATE SYSTEM */
    public void drawCoordinateSystem(int xmax, int ymax, Graphics2D g2d) {
        
    	int xOffset = 30;
        int yOffset = 30;
        int step = 20;
        
        String s;
        
        Font font = g2d.getFont();
        g2d.setFont(new Font("serif",Font.PLAIN,9));

        /* X-AXIS */
        g2d.drawLine(xOffset, yOffset, xmax, yOffset);
       
        /* X-AXIS LABELS*/
        for(int i = xOffset + step; i <= xmax; i = i + step) {
        	g2d.drawLine(i, yOffset - 2, i, yOffset + 2);
            g2d.drawString(String.valueOf(i), i - 7, yOffset - 7);
        }

        /* Y-AXIS */
       g2d.drawLine(xOffset, yOffset, xOffset, ymax);

       /* Y-AXIS LABELS */
       s = "  ";
       
       for(int i = yOffset + step; i <= ymax; i = i + step) {
    	   g2d.drawLine(xOffset-2, i, xOffset + 2, i);
           
    	   if (i > 99) 
        	   s = "";
           
    	   g2d.drawString(s+String.valueOf(i), xOffset - 25, i + 5);
       } 
       g2d.setFont(font);
	}

	public boolean isBusy() {
		
		return busy;
	}
}

